using System;
using Gameplay.PVE.Data;
using System.Collections.Generic;
using Gameplay.PVE.Utils;
using UnityEngine;
using UnityEngine.AI;
using XLua;
using Yoozoo.Libs;
using Yoozoo.Managers;

namespace Gameplay.PVE.Entity
{
    public abstract class UnitBase : IClass
    {
        private List<IComponent> m_components;
        public UnitData Data;
        public GameObject gameObject;
        public GameObject renderer;
        public NavMeshAgent agent;
        public int currentPosIndex = 0;
        public int routeIndex;
        public bool isWaitingTraffic = false;
        public int targetRouteIndex;
        public int targetPosIndex;
        public int waitingRedIndex;
        internal bool smokeYet = false;

        public virtual void Initialize(UnitData data)
        {
            this.Data = data;
            gameObject = new GameObject(data.id.ToString());
            gameObject.transform.SetParent(PveScene.pveRootTrans);
            gameObject.layer = LayerMask.NameToLayer("PveUnit");
            m_components = new List<IComponent>();
        }

        public virtual void OtherResourceComplete()
        {


        }

        public virtual void Update()
        {
            for (int i = 0; i < m_components.Count; i++)
            {
                m_components[i].OnUpdate();
            }
        }

        public virtual void FixedUpdate()
        {

        }

        public virtual void LateUpdate()
        {

        }

        public virtual void BeforeUpdate()
        {

        }

        public void Show()
        {
            if (gameObject != null)
            {
                gameObject.SetActive(true);
            }
        }

        public void Hide()
        {
            if (gameObject != null)
            {
                gameObject.SetActive(false);
            }
        }

        public virtual void Log(object context)
        {

        }

        public void Birth()
        {
            Data.isDead = false;
            OnBirth();
        }

        protected void OnInitialize()
        {
            for (int i = 0; i < m_components.Count; i++)
            {
                m_components[i].OnInitialize(this);
            }
        }

        protected virtual void OnBirth()
        {
            if (Data.summonParent != null)
            {
                Data.summonParent.Data?.AddSummonUnit(Data.id, Data.summonId);
            }
            bool isNext = Data.stage > PveManager.Instance.stageId;
            if (Data.unitType == 0 && !Data.isSummonUnit)
            {
            }
            for (int i = 0; i < m_components.Count; i++)
            {
                m_components[i].OnBirth();
            }
            //gameObject.SetLayerRecursively(PveUtils.pveUnitLayer);
        }

        private void OnDead()
        {
            for (int i = 0; i < m_components.Count; i++)
            {
                m_components[i].OnDead();
            }
        }

        public virtual void SetLayer(int layer)
        {
            if (gameObject != null)
            {
                gameObject.SetLayerRecursively(layer);
            }
        }

        public virtual void SetHudLayer(int layer)
        {
            
        }

        public void Transmit(ETransmitType type, BaseTransmitArg arg = null)
        {
            for (int i = 0; i < m_components.Count; i++)
            {
                if (m_components[i] is ITransmit)
                {
                    ((ITransmit) m_components[i]).OnTransmit(type, arg);
                }
            }
        }

        //临时方法
        public void Transmit(string type, string argName, LuaTable argTable)
        {
            if (Enum.TryParse(type, out ETransmitType transmitType))
            {
                BaseTransmitArg arg = null;
                if (!string.IsNullOrEmpty(argName))
                {
                    arg = PveUtils.GetCsObjectFromLuaTable("Gameplay.PVE."+argName, argTable) as BaseTransmitArg;
                }
                Transmit(transmitType,arg);
            }
        }
        
        public virtual void Dead()
        {
            if (Data.isDead)
            {
                return;
            }
            Data.isDead = true;
            if (Data.summonParent != null)
            {
                Data.summonParent.Data.RemoveSummonUnit(Data.id,Data.summonId);
            }
            OnDead();
            /*if (Data.team == 2)
            {
                for (int i = 0; i < Random.Range(4,8); i++)
                {
                    PveManager.Instance.SpawnItem(Data.position,PveDropType.Money);
                }
            }
            PveManager.Instance.UnitDead(Data.id);*/
        }

        public virtual void SetVisible(bool visible)
        {

        }

        protected T AddComponent<T>() where T : IComponent
        {
            var component = ClassManager.Get<T>();
            if (!m_components.Contains(component))
            {
                m_components.Add(component);
            }
            return component;
        }

        public virtual void Play(string name, float speed = 1)
        {

        }

        public virtual void PlaySkill(string name)
        {

        }

        public virtual void SetHpChange(float change, bool ignoreShield = false)
        {
            
        }
        
        public virtual void SetMpChange(float change)
        {
            
        }

        public virtual void SetDirection()
        {

        }

        public virtual void SetAnimatorSpeed(float speed)
        {

        }


        void IClass.OnReset()
        {
            for (int i = 0; i < m_components.Count; i++)
            {
                ClassManager.Free(m_components[i]);
            }
            m_components.Clear();
            if (gameObject != null)
            {
                GameObject.Destroy(gameObject);
                gameObject = null;
            }
            else
            {
                Debug.Log(Data.id + " 已经被销毁");
            }
            ClassManager.Free(Data);
            Data = null;
            Dispose();
        }

        protected virtual void Dispose()
        {

        }

        public virtual void ValidateShadow(bool enable)
        {
            
        }
    }
}
